package com.swak.vertx.access;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.swak.Constants;
import com.swak.registry.URL;
import com.swak.security.Principal;
import com.swak.security.Subject;
import com.swak.utils.StringUtils;
import com.swak.vertx.remote.IP;

import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;

/**
 * Access.
 * 
 * @author 618lf
 */
public class Access implements io.vertx.core.Handler<RoutingContext> {

	private static Logger logger = LoggerFactory.getLogger(Access.class);

	@Override
	public void handle(RoutingContext context) {
		long start = System.currentTimeMillis();
		context.response().endHandler((e) -> end(context, start));
		context.next();
	}

	/**
	 * 记录如下的信息：<br>
	 * 
	 * userId -- 用户ID<br>
	 * userName -- 用户名称<br>
	 * tenantId -- 商户ID<br>
	 * tenantName -- 商户名称<br>
	 * url -- 请求资源 <br>
	 * method -- 请求方式<br>
	 * ip -- 客户地址<br>
	 * start -- 开始时间<br>
	 * times -- 使用的时间<br>
	 * error -- 是否有错误<br>
	 * module -- 模块<br>
	 * function -- 功能<br>
	 * tenantId -- 商户<br>
	 * tenantName-- 商户<br>
	 * 
	 * @param context
	 * @param start
	 */
	void end(RoutingContext context, long start) {
		if (!logger.isInfoEnabled()) {
			return;
		}
		long end = System.currentTimeMillis();
		URL url = context.get(Constants.URL_NAME);
		Subject subject = context.get(Constants.SUBJECT_NAME);
		Throwable e = context.get(Constants.EXCEPTION_NAME);
		Principal principal = subject.getPrincipal();
		Long userId = principal != null ? principal.getIdAsLong() : null;
		String userName = principal != null ? principal.getName() : null;
		Long tenantId = principal != null ? principal.getTenantIdAsLong() : null;
		String tenantName = principal != null ? principal.getTenantName() : null;
		String requestUrl = context.request().uri();
		String method = context.request().method().name();
		String ip = IP.getRemoteAddr(context.request());
		String module = url != null ? url.getParameter(Constants.Registry_Flux_Api_Module_Key) : StringUtils.EMPTY;
		String function = url != null ? url.getParameter(Constants.Registry_Flux_Api_Function_Key) : StringUtils.EMPTY;
		String describe = url != null ? url.getParameter(Constants.Registry_Flux_Api_Describe_Key) : StringUtils.EMPTY;
		String platform = context.request().getHeader(Constants.Platform_NAME);
		String appId = context.request().getHeader(Constants.App_NAME);
		String openId = context.request().getHeader(Constants.Open_NAME);

		logger.info("{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}", // 格式化
				userId == null ? "\\N" : userId, // 0 : 用户ID
				StringUtils.defaultIfBlank(userName, "\\N"), // 1 :用户名称
				StringUtils.defaultIfBlank(requestUrl, "\\N"), // 2 ：访问资源地址
				StringUtils.defaultIfBlank(method, "\\N"), // 3：请求的方式
				StringUtils.defaultIfBlank(ip, "\\N"), // 4：请求的地址
				start, // 5：开始时间
				end, // 6：结束时间
				end - start, // 7：处理时间
				e == null ? 1 : 0, // 8：是否运行成功
				StringUtils.defaultIfBlank(module, "\\N"), // 9：模块
				StringUtils.defaultIfBlank(function, "\\N"), // 10：功能
				StringUtils.defaultIfBlank(describe, "\\N"), // 11： 描述
				tenantId == null ? "\\N" : tenantId, // 12: 商户
				StringUtils.defaultIfBlank(tenantName, "\\N"), // 13: 商户
				StringUtils.defaultIfBlank(platform, "\\N"), // 14 平台
				StringUtils.defaultIfBlank(appId, "\\N"), // 15 APP id
				StringUtils.defaultIfBlank(openId, "\\N")// 16 open id
		);
	}

	/**
	 * 开启访问记录
	 * 
	 * @return
	 */
	public static Handler<RoutingContext> access() {
		return new Access();
	}
}
